package com.cocotingo.snail;

import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration;
import java.awt.Transparency;
import java.awt.image.BufferedImage;
import java.awt.image.VolatileImage;


public class StretchableImage extends AcceleratedImage {
	
	protected final int x1, x2, y1, y2;
	
	public StretchableImage(GraphicsConfiguration gc, ImageSourceLoader loader, int x1, int y1, int x2, int y2) {
		super(gc, loader);
		this.x1 = x1;
		this.x2 = x2;
		this.y1 = y1;
		this.y2 = y2;
	}
	
	public StretchableImage(GraphicsConfiguration gc, ImageSourceLoader loader, int capWidth, int capHeight) {
		super(gc, loader);
		this.x1 = capWidth;
		this.x2 = this.width - capWidth;
		this.y1 = capHeight;
		this.y2 = this.height - capHeight;
	}
	
	public StretchableImage(GraphicsConfiguration gc, ImageSourceLoader loader, int borderThickness) {
		super(gc, loader);
		this.x1 = borderThickness;
		this.x2 = this.width - borderThickness;
		this.y1 = borderThickness;
		this.y2 = this.height - borderThickness;
	}
	
	@Override
	public void paintOnScreen(Graphics2D g, int left, int top) {
		throw new UnsupportedOperationException("can't paint StretchableImage via drawImage method.");
	}
	
	@Override
	public void paintOnScreen(Graphics2D g, int left, int top, int width, int height) {
		throw new UnsupportedOperationException("can't paint StretchableImage via drawImage method.");
	}
	
	public void paintStretchableImageOnScreen(Graphics2D g, int w, int h) {
		BufferedImage img = null;
		do {
	        int returnCode = vImg.validate(gc);
	        if (returnCode == VolatileImage.IMAGE_RESTORED) {
	        	if (img == null) img = loader.loadImage();
	            renderOffscreen(img);
	        } else if (returnCode == VolatileImage.IMAGE_INCOMPATIBLE) {
	        	if (img == null) img = loader.loadImage();
	            vImg = gc.createCompatibleVolatileImage(width, height, Transparency.TRANSLUCENT);
	            renderOffscreen(img);
	        }
	        
	        if (w <= 0 || h <= 0) return;
			
			int sx1 = this.x1;
			int sx2 = this.x2;
			int sy1 = this.y1;
			int sy2 = this.y2;
			
			int x1 = this.x1;
			int x2 = w - width + this.x2;
			if (x2 < x1) {
				sx1 = x1 = x2 = w / 2;
				sx2 = width - sx1;
			}
			
			int y1 = this.y1;
			int y2 = h - height + this.y2;
			if (y2 < y1) {
				sy1 = y1 = y2 = h / 2;
				sy2 = height - sy1;
			}
			
			// four corners
			g.drawImage(vImg, 0, 0, x1, y1, 0, 0, sx1, sy1, null);
			g.drawImage(vImg, x2, 0, w, y1, sx2, 0, width, sy1, null);
			g.drawImage(vImg, 0, y2, x1, h, 0, sy2, sx1, height, null);
			g.drawImage(vImg, x2, y2, w, h, sx2, sy2, width, height, null);
			
			// four borders
			if (x2 > x1) {
				g.drawImage(vImg, x1, 0, x2, y1, sx1, 0, sx2, sy1, null);
				g.drawImage(vImg, x1, y2, x2, h, sx1, sy2, sx2, height, null);
			}
			if (y2 > y1) {
				g.drawImage(vImg, 0, y1, x1, y2, 0, sy1, sx1, sy2, null);
				g.drawImage(vImg, x2, y1, w, y2, sx2, sy1, width, sy2, null);
			}
			
			// center
			if (x2 > x1 && y2 > y1) {
				g.drawImage(vImg, x1, y1, x2, y2, sx1, sy1, sx2, sy2, null);
			}
	        
		} while (vImg.contentsLost());
		if (img != null) {
			loader.unloadImage(img);
		}
	}
	
}
